package com.pro.framework.web.config;

import com.pro.framework.api.FrameworkConst;
import io.undertow.server.DefaultByteBufferPool;
import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Locale;

@Configuration
@DependsOn("jTDServiceImpl")
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private ILoginInfoArgumentResolver loginInfoArgumentResolver;

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(String.class, LocalDateTime.class, source -> {
            if (source == null || source.trim().isEmpty()) {
                return null;
            }
            String text = source.trim();
            // 支持多种格式
            List<DateTimeFormatter> formatters = List.of(
                    DateTimeFormatter.ISO_LOCAL_DATE_TIME, // 2025-08-13T22:32:03
                    FrameworkConst.DateTimes.DATE_TIME_FORMAT // 2025-08-13 22:32:03
            );
            for (DateTimeFormatter formatter : formatters) {
                try {
                    return LocalDateTime.parse(text, formatter);
                } catch (Exception ignored) {
                }
            }
            throw new IllegalArgumentException("Invalid date time format: " + source);
        });
    }
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(loginInfoArgumentResolver);
    }

    @Bean
    public LocaleResolver localeResolver() {
        return new AcceptHeaderLocaleResolver() {
            @Override
            public Locale resolveLocale(HttpServletRequest request) {
                String lang = request.getHeader("Accept-Language");
                if (lang == null || lang.isEmpty()) {
                    return Locale.getDefault(); // 默认语言
                }
                String[] parts = lang.split("[-_]");
                String lowerCase = parts[0].toLowerCase();
                switch (lowerCase) {
                    case "und":
                        lowerCase = "en"; // und似乎是异常的国家码
                        break;
                }
                return new Locale(lowerCase); // 只取 "zh-CN" 中的 "zh"
            }
        };
    }

    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOriginPattern("*");
//        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        config.setAllowCredentials(true);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);

        return new CorsFilter(source);
    }

    /**
     * 和 knife4j-spring-boot-starter 依赖有关，而这个库是基于 springfox 的，而 springfox 在 Spring Boot 2.6+ 之后和 Spring MVC 产生了一些兼容性问题，尤其是路径匹配策略的变化。
     */
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer.setPatternParser(null);
    }

    @Bean
    public UndertowServletWebServerFactory undertowFactory() {
        UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
        factory.addDeploymentInfoCustomizers(info -> {
            WebSocketDeploymentInfo wsInfo = new WebSocketDeploymentInfo()
                    .setBuffers(new DefaultByteBufferPool(false, 1024 * 1024));
            info.addServletContextAttribute(WebSocketDeploymentInfo.ATTRIBUTE_NAME, wsInfo);
        });
        return factory;
    }


}
